using AhpilyServer;
using AhpilyServers;
using Protocol.Constant;
using Protocol.Dto.Fight;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GameServer.Cache.Fight
{
    /// <summary>
    /// 战斗房间
    /// </summary>
    public class FightRoom
    {
        /// <summary>
        /// 房间的唯一标识码
        /// </summary>
        public int Id { get; private set; }
        /// <summary>
        /// 存储玩家
        /// </summary>
        public List<PlayerDto> PlayerList { get; set; }

        /// <summary>
        /// 中途退出玩家id的列表
        /// </summary>
        public List<int> LeaveUIdList { get; set; }

        /// <summary>
        ///  牌库
        /// </summary>
        public LibraryModel libraryModel { get; set; }

        /// <summary>
        /// 底牌
        /// </summary>
        public List<CardDto> TableCardList { get; set; }

        /// <summary>
        /// 倍数
        /// </summary>
        public int Mutiple { get; set; }

        /// <summary>
        /// 回合管理类
        /// </summary>
        public RoundModel roundModel { get; set; }

        public FightRoom(int id, List<int> uidList)
        {
            this.Id = id;
            this.PlayerList = new List<PlayerDto>();
            foreach (int uid in uidList)
            {
                PlayerDto player = new PlayerDto(uid);
                this.PlayerList.Add(player);
            }
            this.LeaveUIdList = new List<int>();
            this.libraryModel = new LibraryModel();
            this.TableCardList = new List<CardDto>();
            this.Mutiple = 1;
            this.roundModel = new RoundModel();
        }
        public void Init(List<int> uidList)
        {
            foreach (int uid in uidList)
            {
                PlayerDto player = new PlayerDto(uid);
                this.PlayerList.Add(player);
            }
        }
        public bool IsOffline(int uid)
        {
            return LeaveUIdList.Contains(uid);
        }
        /// <summary>
        ///  转换出牌
        /// </summary>
        public int Turn()
        {
            int currUId = roundModel.CurrentUId;
            int nextUId = GetNextUId(currUId);
            // 更改回合信息
            roundModel.CurrentUId = nextUId;
            return nextUId;
        }

        /// <summary>
        /// 计算下一个出牌者
        /// </summary>
        public int GetNextUId(int curUId)
        {
            for (int i = 0; i < PlayerList.Count; i++)
            {
                if (PlayerList[i].UserId == curUId)
                {
                    if (i == 2)
                        return PlayerList[0].UserId;
                    else
                        return PlayerList[i + 1].UserId;
                }
            }
            throw new Exception("无此出牌者");
        }
        /// <summary>
        /// 能否压死上一轮的牌
        /// </summary>
        public bool DealCard(int type, int weight, int length, int userId, List<CardDto> cardList)
        {
            bool canDeal = false;

            if (type == roundModel.LastCardType && weight > roundModel.LastWeight)
            {
                // 特殊类型
                if (type == CardType.STRAIGHT || type == CardType.DOUBLE_STRAIGHT || type == CardType.TRIPLE_STRAIGHT)
                {
                    if (length == roundModel.LastLength)
                    {
                        //满足出牌条件
                        canDeal = true;
                    }
                }
                else
                {
                    canDeal = true;
                }

            }
            else if (type == CardType.BOOM && roundModel.LastCardType != CardType.BOOM)
            {
                // 满足出牌条件
                canDeal = true;
            }
            else if (type == CardType.JOKER_BOOM)
            {
                // 满足出牌条件
                canDeal = true;
            }
            // 第一次出牌,或者自己是最大出牌者
            else if (userId == roundModel.BiggestUId)
            {
                canDeal = true;
            }

            if (canDeal == true)
            {
                // 移除手牌
                removeCards(userId, cardList);
                // 处理倍数
                if (type == CardType.BOOM)
                {
                    Mutiple *= 2;
                }
                else if (type == CardType.JOKER_BOOM)
                {
                    Mutiple *= 4;
                }

                // 保存回合信息
                roundModel.Change(length, type, weight, userId);
            }
            return canDeal;
        }
        /// <summary>
        /// 移除玩家的手牌
        /// </summary>
        private void removeCards(int userId, List<CardDto> cardList)
        {
            List<CardDto> curList = GetUserCards(userId);
            List<CardDto> list = new List<CardDto>();
            foreach (var select in cardList)
            {
                for (int i = curList.Count - 1; i >= 0; i--)
                {
                    if(curList[i].Name == select.Name)
                    {
                        list.Add(curList[i]);
                        break;
                    }
                }
            }
            foreach (var card in list)
            {
                curList.Remove(card);
            }
        }
        /// <summary>
        /// 获取玩家的手牌
        /// </summary>
        public List<CardDto> GetUserCards(int userId)
        {
            foreach (PlayerDto player in PlayerList)
            {
                if (player.UserId == userId)
                {
                    return player.CardList;
                }
            }
            throw new Exception("不存在此玩家");
        }

        /// <summary>
        /// 发牌
        /// </summary>
        public void InitPlayerCards()
        {
            // 总54 平均17 余3
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 17; j++)
                {
                    CardDto card = libraryModel.Deal();
                    PlayerList[i].CardList.Add(card);
                    //PlayerList[i].Add(card);
                }
            }

            // 发底牌
            for (int i = 0; i < 3; i++)
            {
                CardDto card = libraryModel.Deal();
                TableCardList.Add(card);
            }
        }

        /// <summary>
        /// 设置地主身份
        /// </summary>
        public void SetLandLoad(int userId)
        {
            foreach (PlayerDto player in PlayerList)
            {
                if (player.UserId == userId)
                {
                    // 找到了
                    player.Identity = Identity.LANDLOAD;
                    for (int i = 0; i < TableCardList.Count; i++)
                    {
                        player.Add(TableCardList[i]);
                        // 开始回合
                        roundModel.Start(userId);
                    }
                    Sort();
                }
            }
        }

        public PlayerDto GetPlayerModel(int userId)
        {
            foreach (PlayerDto player in PlayerList)
            {
                if (player.UserId == userId)
                {
                    return player;
                }
            }
            throw new Exception("无此玩家");
        }

        public int GetPlayerIdentity(int userId)
        {
            return GetPlayerModel(userId).Identity;
            throw new Exception("无此玩家");
        }

        /// <summary>
        /// 返回相同身份的角色id集合
        /// </summary>
        public List<int> GetSameIdentityUids(int identity)
        {
            List<int> uids = new List<int>();
            foreach (PlayerDto player in PlayerList)
            {
                if (player.Identity == identity)
                {
                    uids.Add(player.UserId);
                }
            }
            return uids;
        }

        /// <summary>
        /// 返回相同身份的角色id集合
        /// </summary>
        public List<int> GetDifferentIdentityUids(int identity)
        {
            List<int> uids = new List<int>();
            foreach (PlayerDto player in PlayerList)
            {
                if (player.Identity != identity)
                {
                    uids.Add(player.UserId);
                }
            }
            return uids;
        }
        /// <summary>
        /// 获取房间内第一个玩家的id
        /// </summary>
        public int GetFirstUId()
        {
            return PlayerList[0].UserId;
        }
        /// <summary>
        /// 手牌排序
        /// </summary>
        public void sortCard(List<CardDto> cardList, bool asc = true)
        {
            cardList.Sort(delegate (CardDto a, CardDto b)
            {
                if (asc)
                    return a.Weight.CompareTo(b.Weight);
                else
                    return a.Weight.CompareTo(b.Weight) * -1;
            });
        }

        public void Sort(bool asc = true)
        {
            sortCard(PlayerList[0].CardList, asc);
            sortCard(PlayerList[1].CardList, asc);
            sortCard(PlayerList[2].CardList, asc);
            sortCard(TableCardList, asc);
        }

        /// <summary>
        /// 广播房间内的所有玩家信息
        /// </summary>
        public void Brocast(int opCode, int subCode, object value, ClientPeer curClient = null)
        {
            SocketMsg msg = new SocketMsg(opCode, subCode, value);
            byte[] data = EncodeTools.EncodeMsg(msg);
            byte[] packet = EncodeTools.EncodePacket(data);
            //foreach (var client in UIdClientDict.Values)
            //{
            //    if (client == curClient)
            //        continue;
            //    client.Send(packet);
            //}
            foreach (PlayerDto player in PlayerList)
            {
                // 用户下线
                if(Caches.User.IsOnline(player.UserId) == false)
                {
                    continue;
                }
                ClientPeer client = Caches.User.GetClientPeer(player.UserId);
                if(client == curClient)
                {
                    continue;
                }
                client.Send(packet);
            }
        }
    }
}
